import os
import sys
import log
from win32crypt import CryptProtectData, CryptUnprotectData

logger = log.setup_custom_logger('root')
logger.debug('Program started')

# import submodules here
import computer
import filemanager
import defaults
import getnetworkhosts
import getinput

try:
    from configuration import CONFIG
    """
    Configuration options:
    SCAN_PATH
    RUN_AS_LOCAL
    HOST_LIST
    HOST_FILE
    OUTPUT_FORMAT
    """
except:
    print 'No configuration file found.'
    sys.exit(-1)
else:
    if None in CONFIG.values():
        logger.error('One or more options set to "None"; please complete configuration.')
        sys.exit(-1)

responses = getinput.GetUserInput()


class ScanManager(object):

    def __init__(self):
        self.scannedHosts = []
        self.hostSummary = {}
        logger.info('Begin scan process.')
        self.get_hosts()
        if not CONFIG['RUN_AS_LOCAL']:
            self.get_credentials()
        self.get_event_history()
        self.fileOutputPath = self.check_directory_structure()

    def get_hosts(self):
        logger.info('Getting a list of hosts to scan.')
        if CONFIG['HOST_LIST']:
            nh = getnetworkhosts.GetNetworkHosts(hlist=CONFIG['HOST_LIST'])
        elif CONFIG['HOST_FILE']:
            nh = getnetworkhosts.GetNetworkHosts(hfile=CONFIG['HOST_FILE'])
        else:
            nh = getnetworkhosts.GetNetworkHosts()
        self.hosts = nh.hosts
        logger.info('Found {} hosts.'.format(len(self.hosts)))
        print nh
        self.nh = nh

    def get_credentials(self):
        import getpass
        logger.info('Getting credentials.')
        self.uname = CryptProtectData(raw_input('Enter username: '), '', None, None, None, 0)
        self.pword = CryptProtectData(getpass.win_getpass(), '', None, None, None, 0)
        logger.info('Credentials stored.')

    def get_event_history(self):
        logger.info('Getting event history.')
        self.eventHistory = responses.ask('Event history? (0=all, -1=none)', 'num')
        print ''
        logger.info('Event history set to: {}'.format(self.eventHistory))

    def check_directory_structure(self):
        cwd = os.getcwd()
        fileOutputPath = os.path.join(cwd, CONFIG['SCAN_PATH'], defaults.FOLDER_MONTH,
                                      defaults.FOLDER_DAY, defaults.FOLDER_TIME)
        logger.info('Creating directories.')
        try:
            os.makedirs(fileOutputPath)
        except WindowsError as e:
            logger.warning('Could not create folder.  May already exist: {}'.format(e))
        else:
            logger.info('Path {} created.'.format(fileOutputPath))
        return fileOutputPath

    def scan_all_hosts(self):
        logger.info('Starting scan process.')
        for host in self.hosts:
            currHost = self.scan_host(host)
            if currHost:
                logger.info('Adding host summary data to hostSummary.')
                self.hostSummary.update(currHost.build_summary())
                self.write_host_to_file(currHost)
                logger.info('***** END {} *****'.format(host[1]))
                self.scannedHosts.append(currHost)
        
    def scan_host(self, host):
        logger.info('***** {} *****'.format(host[1]))
        print 'Host {}'.format(host[1].upper())
        currHost = computer.Computer(host, defaults.SCAN_DATE)
        if not CONFIG['RUN_AS_LOCAL']:
            status = currHost.connect(CryptUnprotectData(self.uname, None, None, None, 0)[1],
                                      CryptUnprotectData(self.pword, None, None, None, 0)[1])
        else:
            status = currHost.connect()
        if not status:
            logger.error('Could not connect to host.')
            print '  No connection available.'
            return False

        def print_to_screen(obj, name, *args):
            print '  {}...'.format(name),
            try:
                result = obj(*args)
            except AttributeError:
                logger.error('Error with WMI attributes, skipping host.')
                print '\n  There was an error; this host will be skipped.'
            else:
                if result:
                    print 'done: [{}].'.format(result),
                else:
                    print 'done.'

        print_to_screen(currHost.get_system, 'System')
        print_to_screen(currHost.get_os, 'OS')
        print_to_screen(currHost.get_disks, 'Disks')
        print_to_screen(currHost.get_shares, 'Shares')
        print_to_screen(currHost.get_printers, 'Printers')
        print_to_screen(currHost.get_events, 'Events', self.eventHistory)
        print '\n'
        return currHost

    def write_host_to_file(self, host):
        logger.info('Writing data to individual host file.')
        hostFile = filemanager.HostWorkbook(os.path.join(self.fileOutputPath, host.hostName + '.xls'))
        hostFile.add_host_data(host.summary)
        if host.events.count > 0:
            summary, complete = host.events.output()
            hostFile.add_sheet('Events Summary')
            hostFile.write_to_sheet('Events Summary', summary)
            hostFile.add_sheet('All Events')
            hostFile.write_to_sheet('All Events', complete)
        hostFile.finalize_book()
        logger.info('File complete.')


def copy_log(path):
    import shutil
    shutil.copy('network_scan.log', path)





def main():
    sm = ScanManager()
    sm.scan_all_hosts()
    fm = filemanager.SummaryWorkbook(os.path.join(sm.fileOutputPath, 'summary.xls'))
    summary = fm.build_summary(sm.hostSummary)
    fm.write_to_summary(summary)
    fm.finalize_book()
    copy_log(sm.fileOutputPath)
    import subprocess
    subprocess.Popen(['explorer.exe', sm.fileOutputPath])





if __name__ == "__main__":
    main()